/**
 * 需要全局变量：$和moment，
 * 需要knockout及knockout-amd-helper，
 * 需要perfect-scrollbar.jquery.js
 */
(function (factory) {
    if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
        factory(require("knockout"), exports, require('moment'));
    } else if (typeof define === "function" && define["amd"]) {
        define(["knockout", "exports", 'moment', "hr.common"], factory);
    } else {
        factory(ko, ko.common = {});
    }
}(function (ko, exports, moment, common) {
    if (typeof (ko) === 'undefined') {
        throw new Error('Knockout is required, please ensure it is loaded before loading this ko.common plug-in');
    }

    ko.common = exports;

    exports.templatePath = "src/hr/";

    /**
     * 重新绑定
     */
    ko.bindingHandlers.htmlWithBinding = {
        'init': function() {
            return { 'controlsDescendantBindings': true };
        },
        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            ko.utils.setHtml(element, valueAccessor());
            ko.applyBindingsToDescendants(bindingContext.$module, element);
        }
    };

    /**
     * 跳过绑定
     */
    ko.bindingHandlers.stopBinding = {
        init: function(){
            return {controlsDescendantBindings: true};
        }
    };

    /**
     * 绑定时间控件
     */
    ko.bindingHandlers.datetimepicker = {
        init: function(element, valueAccessor){
            $(element).datetimepicker(ko.unwrap(valueAccessor()));
        }
    };

    /**
     * label
     */
    ko.bindingHandlers.koLabel = {
        init: function (element, valueAccessor) {
            var params = ko.unwrap(valueAccessor());
            var initParams = {
                className: 'u-label u-label-default'
            };
            params = $.extend($.extend({}, initParams), params);
            $(element).addClass(params.className);
        },
        update: function (element, valueAccessor) {
            var params = valueAccessor();
            if (params) {
                var className = ko.unwrap(params.css);
                if (className) {
                    $(element).removeClass();
                    $(element).addClass(className);
                }
            }
        }
    };

    /**
     * 输入框
     */
    ko.bindingHandlers.koInput = {
        init: function (element, valueAccessor) {
            var params = ko.unwrap(valueAccessor());
            var initParams = {
                css: 'u-input u-input-default'
            };
            params = $.extend($.extend({}, initParams), params);
            $(element).addClass(params.css);
        },
        update: function (element, valueAccessor) {
            var params = valueAccessor();
            if (params) {
                if (ko.unwrap(params.disabled)) {
                    $(element).attr({disabled: 'disabled'});
                } else {
                    $(element).removeAttr('disabled');
                }
                if (ko.unwrap(params.readonly)) {
                    $(element).attr({readonly: 'readonly'});
                } else {
                    $(element).removeAttr('readonly');
                }
            }
        }
    };

    /**
     * 按钮
     */
    ko.bindingHandlers.koButton = {
        init: function (element, valueAccessor) {
            var params = ko.unwrap(valueAccessor());
            var initParams = {
                className: 'u-btn u-btn-default u-no-icon'
            };
            params = $.extend($.extend({}, initParams), params);
            $(element).addClass(params.className);
        },
        update: function (element, valueAccessor) {
            var params = valueAccessor();
            if (params) {
                var className = ko.unwrap(params.css);
                if (className) {
                    $(element).removeClass();
                    $(element).addClass(className);
                }
            }
        }
    };

    /**
     * 单选框
     */
    ko.bindingHandlers.koCheckBox = {
        init: function (element, valueAccessor) {
            $(element).html('<i class="icon-ok-4"></i>');
            var params = ko.unwrap(valueAccessor());
            var radioGroupParams = {
                uCheckboxClassName: 'u-checkbox'
            };
            params = $.extend($.extend({}, radioGroupParams), params);
            $(element).addClass(params.uCheckboxClassName);
        },
        update: function (element, valueAccessor) {
        }
    };

    /**
     * 单选框组
     */
    ko.bindingHandlers.koCheckBoxGroup = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var params = ko.unwrap(valueAccessor());
            var checkBoxGroupParams = {
                checkBoxData: ko.observableArray(),
                checkBoxTextClass: ko.observable('exe'),
                checkedItems: ko.observableArray([{'id': '1', 'text': '男'}]),
                customId: 'id',
                customText: 'text',
                clickCheckBox: function (data, event) {
                    if ($(event.currentTarget).hasClass('u-checked')) {
                        params.checkedItems.remove(data);
                        $(event.currentTarget).removeClass('u-checked');
                    } else {
                        params.checkedItems.push(data);
                        $(event.currentTarget).addClass('u-checked');
                    }
                },
                clickCheckBoxAll: function () {

                }
            };
            //合并参数
            params = $.extend($.extend({}, checkBoxGroupParams), params);
            //绑定模板
            ko.renderTemplate(exports.templatePath+"koCheckBoxGroup", params, {}, element, "replaceChildren");
        },
        update: function (element, valueAccessor) {
        }
    };

    /**
     * 复选框
     */
    ko.bindingHandlers.koRadio = {
        init: function (element, valueAccessor) {
            var params = ko.unwrap(valueAccessor());
            $(element).html('<div></div>');
            var radioGroupParams = {
                uRadioClassName: 'u-radio u-radio-div'
            };
            params = $.extend($.extend({}, radioGroupParams), params);
            $(element).addClass(params.uRadioClassName);
        },
        update: function (element, valueAccessor) {
        }
    };

    /**
     * 复选框组
     */
    ko.bindingHandlers.koRadioGroup = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var params = ko.unwrap(valueAccessor());
            var radioGroupParams = {
                customId: 'id',
                customText: 'text',
                radioData: ko.observableArray([{'id': '1', 'text': '男'}, {'id': '2', 'text': '女'}]),
                radioTextClass: ko.observable('exe'),
                checkedItem: ko.observable({'id': '1', 'text': '男'}),
                clickRadio: function (data, event, index) {
                    params.checkedItem(data);
                    $(event.currentTarget).parent().find('.u-radio-checked').removeClass('u-radio-checked');
                    $(event.currentTarget).addClass('u-radio-checked');
                },
                showCustomId: function (data, customId) {
                    var customData = '';
                    if(data){
                        customData = data[customId]
                    }
                    return customData;
                },
                showCustomText: function (data, customText) {
                    var customData = '';
                    if(data){
                        var customs = customText.split('.');
                        customData = data;
                        $.each(customs, function(index, item){
                            customData = customData[item];
                        });
                    }
                    return customData;
                }
            };
            //合并参数
            params = $.extend($.extend({}, radioGroupParams), params);
            //绑定模板
            ko.renderTemplate(exports.templatePath+"koRadioGroup", params, {}, element, "replaceChildren");

        },
        update: function (element, valueAccessor) {
            var params = valueAccessor();
        }
    };

    /**
     * 不可输入下拉框
     */
    ko.bindingHandlers.koSelect = {
        init: function (element, valueAccessor) {
            var initParams = {
                uChooseClassName: 'u-choose u-input-choose',
                className: 'u-input u-input-default',
                iClassName: 'icon-down-dir',
                ulHeight: ko.observable('180px'),
                customId: 'id',
                customText: 'text',
                initSelectItem: ko.observable(),
                selectData: ko.observableArray([]),
                isShowHint: true,
                inputReadonly: true,
                searchText: ko.observable(),
                clickSelectLi: function (data, event) {
                },
                showCustomText: function (data, customText) {
                    var customData = '';
                    if(data){
                        var customs = customText.split('.');
                        customData = data;
                        $.each(customs, function(index, item){
                            customData = customData[item];
                        });
                    }
                    return customData;
                },
                inputKeyUp: function (data, event) {
                    params.searchText(event.currentTarget.value);
                }
            };
            var params = ko.unwrap(valueAccessor());
            params = $.extend($.extend({}, initParams), params);

            if (ko.unwrap(params.isShowHint)) {
                var emptyItem = {};
                emptyItem[params.customId] = '';
                emptyItem[params.customText] = '请选择';
                params.emptyItem = emptyItem;
            }
            if (params.selectData.filter) {
                params.selectDataFilter = params.selectData.filter(function (t) {
                    if (!params.searchText()) {
                        return true;
                    }
                    return t[params.customText].indexOf(params.searchText()) > -1;
                });
            } else {
                params.selectDataFilter = params.selectData;
            }

            $(element).addClass(params.uChooseClassName);
            ko.renderTemplate(exports.templatePath+"koSelect", params, {
                afterRender: function () {
                    $(element).find('ul').perfectScrollbar();
                    params.initSelectItem.subscribe(function(){
                        $(element).find('ul').perfectScrollbar('update');
                    });
                }
            }, element, "replaceChildren");

        },
        update: function (element, valueAccessor) {
        }
    };

    /**
     * 可输入下拉框
     */
    ko.bindingHandlers.koEnterSelect = {
        init: function (element, valueAccessor) {
            var initParams = {
                initSelectData: [],
                uChooseClassName:'u-choose u-input-choose',
                className: 'u-input u-input-default',
                iClassName: 'icon-down-dir',
                ulHeight: ko.observable('128px'),
                customId:'id',
                customText: 'text',
                customTextChild: '',
                initSelectItem: ko.observable(),
                clickSelectLi : function (data, event) {
                },
                showCustomText: function (data, customText) {
                    var customData = '';
                    if(data){
                        var customs = customText.split('.');
                        customData = data;
                        $.each(customs, function(index, item){
                            customData = customData[item];
                        });
                    }
                    return customData;
                },
                inputKeyUp: function (data, event) {
                    var selectData = data.initSelectData;
                    var newArray = new Array();
                    $.each(selectData, function (index, item) {
                        var customs = params.customText.split('.');
                        var customData = item;
                        var customPyData = item;
                        $.each(customs, function(index, item){
                            customData = customData[item];
                            if(index == (customs.length-1)){
                                customPyData = customPyData[item+"Py"];
                            }
                        });
                        if(customData.indexOf(event.currentTarget.value) > -1 || (customPyData && customPyData.indexOf(event.currentTarget.value) > -1)){
                            newArray.push(item);
                        }
                    });
                    params.selectData(newArray);
                }
            };
            var params = ko.unwrap(valueAccessor());
            params = $.extend($.extend({}, initParams), params);
            if(params.selectData()){
                if(params.initSelectData.length == 0){
                    params.initSelectData = params.selectData();
                }
            }else{
                params.selectData.subscribe(function(data){
                    if(params.initSelectData.length == 0){
                        params.initSelectData = data;
                    }
                });
            }
            $(element).addClass(params.uChooseClassName);
            ko.renderTemplate(exports.templatePath + "koEnterSelect", params, { afterRender:function () {
                $(element).find('ul').perfectScrollbar();
                params.initSelectItem.subscribe(function(){
                    $(element).find('ul').perfectScrollbar('update');
                });
            } }, element, "replaceChildren");
        },
        update: function (element, valueAccessor) {

        }
    };

    ko.bindingHandlers.koGrid = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var params = ko.unwrap(valueAccessor());
            var tableParams = {
                url: ko.observable(''),//请求数据路径
                params: ko.observable(''),//请求参数
                data: ko.observable(),
                tableData: ko.observableArray([]),
                //列头
                tableMainTheadTableColumns: ko.observableArray([]),
                //操作列
                operationColumns: ko.observableArray([]),
                operationColumnsIsFirst: ko.observable(false),
                //表格title
                tableTitle: ko.observable(''),
                //是否单选
                singleSelect: ko.observable(true),
                ulHeight: ko.observable('160px'),
                //加载数据
                loadData: ko.observable(false),
                //各表格元素样式属性
                tableClass: ko.observable('g-col12 table'),
                tableTitleClass: ko.observable('g-col12 m-table-title'),
                tableMainClass: ko.observable('g-col12 m-table-div'),//
                tableMainTheadClass: ko.observable('g-col12 m-table-thead-div'),
                tableMainTheadTableClass: ko.observable('m-table'),
                tableMainTheadTableThLeftClass: ko.observable('f-tl'),
                tableMainTheadTableThOtherClass: ko.observable('f-text-center'),
                tableMainTbodyClass: ko.observable('g-col12 m-table-tbody-div'),
                tableMainTbodyTableClass: ko.observable('m-table f-text-center'),
                tableMainTbodyTableTrJsClass: ko.observable('m-table-js'),
                tableMainTbodyTableTrOsClass: ko.observable('m-table-os'),
                tableMainPageClass: ko.observable('g-col12 m-table-page'),
                tablePageEachClass: ko.observable('m-table-page-each'),
                tablePageCurrentPageClass: ko.observable('current-page'),
                tablePageTotalPageClass: ko.observable('total-page'),
                tablePageJumpClass: ko.observable('page-jump'),
                tablePageRowsClass: ko.observable('page-rows'),
                tableMainTbodyTableTrSelectClass: ko.observable('m-table-selected'),
                //每页已选条数
                tablePageItem: ko.observable({'id': '10', 'text': '10'}),
                //每页可选条数
                tablePageItems: ko.observableArray([{'id': '10', 'text': '10'}, {'id': '30', 'text': '30'}, {
                    'id': '50',
                    'text': '50'
                }, {'id': '100', 'text': '100'}]),
                //总记录数
                tableDataRowNumbers: ko.pureComputed(function () {
                    var dataObj = ko.unwrap(params.data);
                    var rowNumbers = 0;
                    if (dataObj) {
                        rowNumbers = dataObj.data.totalElements;
                    }
                    return rowNumbers;
                }, this),
                //当前页数
                tablePageCurrentPageNumber: ko.observable(1),
                //总页数
                tablePageTotalPageNumbers: ko.pureComputed(function () {
                    var dataObj = ko.unwrap(params.data);
                    var rowsNum = 1;
                    if (dataObj) {
                        rowsNum = dataObj.data.totalPages;
                    }
                    return rowsNum;
                }, this),
                //已跳转页数
                tablePageJumpCurrentPage: ko.observable({'id': '1', 'text': '1'}),
                //可跳转页数
                tablePageJumpTotalPages: ko.pureComputed(function () {
                    var dataObj = ko.unwrap(params.data);//
                    var dataRowsNum = 1;
                    if (dataObj) {
                        dataRowsNum = dataObj.data.totalPages;
                    }
                    var totalPagesArr = [];
                    for (var i = 0; i < dataRowsNum; i++) {
                        var child = new Object()
                        child.id = i * 1 + 1;
                        child.text = i * 1 + 1;
                        totalPagesArr.push(child);
                    }
                    return totalPagesArr;
                }, this),
                //处理外键关联
                computedValue: function (data, key) {
                    if (key.indexOf(".") > -1) {
                        var subKeyArr = key.split("\.");
                        for (var i = 0, len = subKeyArr.length; i < len; i++) {
                            if (data[subKeyArr[i]]) {
                                data = data[subKeyArr[i]];
                                if ($.isArray(data)) {
                                    var tempData = '';
                                    i++;
                                    $.each(data, function (index, item) {
                                        if (index !== 0) {
                                            tempData += ', ';
                                        }
                                        if (item[subKeyArr[i]]) {
                                            tempData += item[subKeyArr[i]];
                                        }
                                    });
                                    data = tempData;
                                }
                            } else {
                                return '';
                            }
                        }
                    } else {
                        data = data[key];
                    }
                    return data;
                },
                //选中行
                selectRows: ko.observableArray(),
                //点击行
                clickRow: function (item, event) {
                    if (params.singleSelect()) {
                        params.selectRows.removeAll();
                        params.selectRows.push(item);
                        //单选模式，互斥效果
                        if ($(event.currentTarget).hasClass(params.tableMainTbodyTableTrSelectClass())) {
                            $(event.currentTarget).removeClass(params.tableMainTbodyTableTrSelectClass())
                        } else {
                            $(event.currentTarget).parent().find("."+params.tableMainTbodyTableTrSelectClass()).removeClass(params.tableMainTbodyTableTrSelectClass());
                            $(event.currentTarget).addClass(params.tableMainTbodyTableTrSelectClass())
                        }
                    } else {
                        if (ko.utils.arrayIndexOfItem(params.selectRows(),item,'id')) {
                            ko.utils.arrayDeleteItem(params.selectRows(),item,'id')
                        } else {
                            params.selectRows.push(item);
                        }
                        //多选模式，点击即选中
                        if ($(event.currentTarget).hasClass(params.tableMainTbodyTableTrSelectClass())) {
                            $(event.currentTarget).removeClass(params.tableMainTbodyTableTrSelectClass());
                        } else {
                            $(event.currentTarget).addClass(params.tableMainTbodyTableTrSelectClass())
                        }
                    }
                    params.clickRowCallBack && params.clickRowCallBack(params.selectRows());
                },
                getTrClass: function (data, index) {
                    var resultClass = '';
                    if (ko.utils.arrayIndexOfItem(params.selectRows(), data, 'id')) {
                        resultClass = params.tableMainTbodyTableTrSelectClass();
                    } else if (ko.utils.arrayIndexOfItem(params.selectRows(),data,'id')) {
                        resultClass = params.tableMainTbodyTableTrSelectClass();
                    } else if (index % 2 == 1) {
                        resultClass = params.tableMainTbodyTableTrJsClass();
                    } else if (index % 2 == 0){
                        resultClass = params.tableMainTbodyTableTrOsClass();
                    }
                    return resultClass;
                },
                //选择pageNum或pageSize，查询数据
                changePage: function (data, event) {
                    params.tablePageCurrentPageNumber(ko.unwrap(params.tablePageJumpCurrentPage).id);
                    getData();
                },
                //上一页
                previousPage: function () {
                    var dataObj = ko.unwrap(params.data);
                    var data;
                    if (dataObj) {
                        data = dataObj.data;
                        var isFirst = data.first;
                        if (isFirst) {
                            return;
                        } else {
                            //设置跳转
                            var item = new Object();
                            item.id = params.tablePageCurrentPageNumber() * 1 - 1;
                            item.text = params.tablePageCurrentPageNumber() * 1 - 1;
                            params.tablePageJumpCurrentPage(item);
                            //设置当前页数
                            var pageNumber = params.tablePageCurrentPageNumber();
                            params.tablePageCurrentPageNumber(pageNumber * 1 - 1);
                            getData();
                        }
                    }
                },
                //下一页
                nextPage: function () {
                    var dataObj = ko.unwrap(params.data);
                    var data;
                    if (dataObj) {
                        data = dataObj.data;
                        var isLast = data.last;
                        if (isLast) {
                            return;
                        } else {
                            //设置跳转
                            var item = new Object();
                            item.id = params.tablePageCurrentPageNumber() * 1 + 1;
                            item.text = params.tablePageCurrentPageNumber() * 1 + 1;
                            params.tablePageJumpCurrentPage(item);
                            //设置当前页数
                            var pageNumber = params.tablePageCurrentPageNumber();
                            params.tablePageCurrentPageNumber(pageNumber * 1 + 1);
                            getData();
                        }
                    }
                },
                //点击操作项
                clickOperations: function (data, op, event) {
                    var opName = op.clickOperations;
                    bindingContext.$data[opName](data, event);
                    ko.utils.stopBubble(event);
                },
                //自定义格式化
                formatter: function (value, formatObj) {
                    var fuc = formatObj.fun;
                    var format = formatObj.format;
                    if (typeof params[fuc] === 'undefined') {
                        //调用业务定义的格式化方法
                        return bindingContext.$data[fuc](value, formatObj.format);
                    }
                    //调用预设的格式化方法
                    var dateStr = params[fuc](value, format);
                    return dateStr;
                },
                //格式化时间
                formatDate: function (value, format) {
                    if (value) {
                        var dateStr = moment(+value).format(format);
                        return dateStr;
                    } else {
                        return '';
                    }
                }

            };
            //合并参数
            params = $.extend($.extend({}, tableParams), params);
            getData();
            //加载数据
            params.loadData.subscribe(function (va) {
                if (va) {
                    //加载数据前，当前页码重置为1
                    params.tablePageCurrentPageNumber(1);
                    params.tablePageJumpCurrentPage({'id': '1', 'text': '1'});
                    //加载数据
                    getData();
                    //重置加载数据请求
                    params.loadData(false);
                }
            });
            //绑定模板
            //ko.renderTemplate(exports.templatePath+"koGrid", params, {
            //    afterRender: function () {
            //        getTableHeight($(element));
            //    }
            //}, element, "replaceChildren");
            //查询数据
            function getData() {
                common.loadAjax({
                    url: ko.unwrap(params.url()),
                    param: ko.unwrap(params.param()) + "&page=" + (params.tablePageCurrentPageNumber() - 1) + "&rows=" + ko.unwrap(params.tablePageItem()).id
                }).success(function (data) {
                    params.data(data);
                    params.tableData(data.data.content);
                    //绑定模板
                    ko.renderTemplate(exports.templatePath + "koGrid", params, {
                        afterRender: function () {
                            params.tableAfterRender && params.tableAfterRender(element);
                            getTableHeight($(element));
                        }
                    }, element, "replaceChildren");
                });
            }


        },
        update: function (element, valueAccessor) {
        }
    };

    //停止event冒泡
    ko.utils.stopBubble = function(e) {
        //如果提供了事件对象，则这是一个非IE浏览器
        if (e && e.stopPropagation) {
            e.stopPropagation(); //因此它支持W3C的stopPropagation()方法
        } else {
            window.event.cancelBubble = true; //否则，我们需要使用IE的方式来取消事件冒泡
        }
    };

    //判断数组里是否包含某个对象
    ko.utils.arrayIndexOfItem = function (array, item, key) {
        var result = false;
        $.each(array, function (index, obj) {
            if (obj[key] == item[key]) {
                result = true;
                return false;//终止循环
                // return true;//终止本次循环，进入下一次循环
            } else {
                result = false;
            }
        });
        return result;
    };

    //删除数组里某个对象
    ko.utils.arrayDeleteItem = function (array, item, key) {
        var itemIndex = -1;
        $.each(array, function (index, obj) {
            if (obj[key] == item[key]) {
                itemIndex = index;
                return false;//终止循环
            }
        });
        if (itemIndex > -1) {
            array.splice(itemIndex, 1);
        }
        return array;
    };

    if(typeof $ != 'undefined') {
        $(window).resize(function () {
            var gridParent = $(".ko-grid-parent");
            if (gridParent.length > 0) {
                for (var i = 0; i < gridParent.length; i++) {
                    getTableHeight($($(gridParent[i]).children()[0]));
                }
            }
        });
    }

    function getTableHeight(obj) {
        var gridHeight = obj.parent().height();
        var gridTitleHeight = $(obj.children()[0]).height();
        var gridPageHeight = $(obj.children()[2]).height();
        var gridHeaderHeight = $($(obj.children()[1]).children()[0]).height();
        var gridTableHeight = (gridHeight - gridTitleHeight - gridHeaderHeight - gridPageHeight) + "px";
        $($(obj.children()[1]).children()[1]).height(gridTableHeight);
        $($(obj.children()[1]).children()[1]).perfectScrollbar();
    }
}));